//===============================================================================
// Microsoft Architecture Strategy Team
// LitwareHR - SaaS Sample Application
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================

using System;
using System.Collections.Generic;
using System.Security.Permissions;
using Shp.Runtime.Contract;
using System.Threading;
using System.Globalization;

namespace Shp.Runtime.Services
{
    public class AuthenticationService : IAuthenticationUC, IAuthenticationSC
    {
        public void AddUserToRole(string tenantAlias, string username, string roleName)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InstalledUICulture;

            if (String.IsNullOrEmpty(tenantAlias))
                throw (new ArgumentNullException("tenantAlias"));

            if (String.IsNullOrEmpty(username))
                throw (new ArgumentNullException("username"));

            if (String.IsNullOrEmpty(roleName))
                throw (new ArgumentNullException("roleName"));

            Upn upn = new Upn(username, tenantAlias);
            AuthenticationLogic.AddUserToRole(upn, roleName);
        }

        public void CreateRole(string tenantAlias, string roleName)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InstalledUICulture;

            if (String.IsNullOrEmpty(tenantAlias))
                throw (new ArgumentNullException("tenantAlias"));

            if (String.IsNullOrEmpty(roleName))
                throw (new ArgumentNullException("roleName"));

            if (RoleExists(tenantAlias, roleName))
                throw (new ArgumentException("Role already exists", roleName));

            AuthenticationLogic.CreateRole(tenantAlias.ToLowerInvariant(), roleName);
        }

        public bool DeleteRole(string tenantAlias, string roleName)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InstalledUICulture;

            if (String.IsNullOrEmpty(tenantAlias))
                throw (new ArgumentNullException("tenantAlias"));

            if (String.IsNullOrEmpty(roleName))
                throw (new ArgumentNullException("roleName"));

            return (AuthenticationLogic.DeleteRole(tenantAlias.ToLower(), roleName));
        }

        public bool ValidateUser(string tenantAlias, string user, string password)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InstalledUICulture;

            if (string.IsNullOrEmpty(tenantAlias))
                throw new ArgumentNullException("tenantAlias");
            if (string.IsNullOrEmpty(user))
                throw new ArgumentNullException("user");
            if (string.IsNullOrEmpty(password))
                throw new ArgumentNullException("password");

            Upn upn = new Upn(user, tenantAlias);
            return AuthenticationLogic.ValidateUser(upn, password);
        }

        public bool IsUser(string tenantAlias, string user)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InstalledUICulture;

            if (string.IsNullOrEmpty(tenantAlias))
                throw new ArgumentNullException("tenantAlias");
            if (string.IsNullOrEmpty(user))
                throw new ArgumentNullException("user");

            Upn upn = new Upn(user, tenantAlias);
            return AuthenticationLogic.IsUser(upn);
        }

        public string[] GetRolesForUser(string tenantAlias, string user)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InstalledUICulture;

            if (string.IsNullOrEmpty(tenantAlias))
                throw new ArgumentNullException("tenantAlias");
            if (string.IsNullOrEmpty(user))
                throw new ArgumentNullException("user");

            Upn upn = new Upn(user, tenantAlias);
            return AuthenticationLogic.GetRolesForUser(upn);
        }

        public string[] GetRoles(string tenantAlias)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InstalledUICulture;

            if (String.IsNullOrEmpty(tenantAlias))
                throw new ArgumentNullException("tenantAlias");

            return AuthenticationLogic.GetRoles(tenantAlias.ToLowerInvariant());
        }

        public string[] GetUsers(string tenantAlias)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InstalledUICulture;

            if (string.IsNullOrEmpty(tenantAlias))
                throw new ArgumentNullException("tenantAlias");

            return AuthenticationLogic.GetUsers(tenantAlias);
        }

        public PasswordPolicy GetPasswordPolicy()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InstalledUICulture;

            return AuthenticationLogic.GetPasswordPolicy();
        }

        public bool RoleExists(string tenantAlias, string roleName)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InstalledUICulture;

            if (String.IsNullOrEmpty(tenantAlias))
                throw (new ArgumentNullException("tenantAlias"));

            if (String.IsNullOrEmpty(roleName))
                throw (new ArgumentNullException("roleName"));

            return AuthenticationLogic.RoleExists(tenantAlias, roleName);
        }

        public void RemoveUserFromRole(string tenantAlias, string username, string roleName)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InstalledUICulture;

            if (String.IsNullOrEmpty(tenantAlias))
                throw (new ArgumentNullException("tenantAlias"));

            if (String.IsNullOrEmpty(roleName))
                throw (new ArgumentNullException("roleName"));

            if (String.IsNullOrEmpty(username))
                throw (new ArgumentNullException("username"));

            if (!AuthenticationLogic.RoleExists(tenantAlias, roleName))
                throw (new ArgumentException("Invalid roleName", roleName));

            Upn upn = new Upn(username, tenantAlias);

            if (!AuthenticationLogic.IsUser(upn))
                throw (new ArgumentException("Invalid username"));

            AuthenticationLogic.RemoveUserFromRole(upn, roleName);
        }

        public bool IsUserInRole(string tenantAlias, string username, string roleName)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InstalledUICulture;

            if (String.IsNullOrEmpty(tenantAlias))
                throw (new ArgumentNullException("tenantAlias"));

            if (String.IsNullOrEmpty(roleName))
                throw (new ArgumentNullException("roleName"));

            if (String.IsNullOrEmpty(username))
                throw (new ArgumentNullException("username"));

            Upn upn = new Upn(username, tenantAlias);
            return AuthenticationLogic.IsUserInRole(upn, roleName);
        }
    }
}